package org.example.meetingsystem.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.meetingsystem.entity.MeetingRoom;
import org.example.meetingsystem.enums.RoomStatus;
import org.example.meetingsystem.enums.UserRole;
import org.example.meetingsystem.annotation.RequireAuth;
import org.example.meetingsystem.service.MeetingRoomService;
import org.example.meetingsystem.util.BusinessException;
import org.example.meetingsystem.util.ResponseUtil;
import org.example.meetingsystem.util.Result;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 会议室管理控制器
 */
@Tag(name = "会议室管理")
@RestController
@RequestMapping("/api/meeting-rooms")
@RequiredArgsConstructor
@Slf4j
public class MeetingRoomController {

    private final MeetingRoomService meetingRoomService;

    /**
     * 获取可用会议室列表
     */
    @GetMapping("/available")
    @RequireAuth(roles = {UserRole.CUSTOMER})
    @Operation(summary = "获取可用会议室列表")
    public Result<List<MeetingRoom>> getAvailableRooms(
            @RequestParam(required = false) @Parameter(ref = "最小容量要求") Integer capacity,
            @RequestParam(required = false) @Parameter(ref = "是否需要投影仪") Boolean needProjector,
            @RequestParam(required = false) @Parameter(ref = "是否需要音响") Boolean needAudio,
            @RequestParam(required = false) @Parameter(ref = "是否需要网络") Boolean needNetwork) {

        try {
            List<MeetingRoom> rooms = meetingRoomService.getAvailableRooms(
                    capacity, needProjector, needAudio, needNetwork);
            return ResponseUtil.success(rooms);
        } catch (BusinessException e) {
            return ResponseUtil.error(e.getMessage());
        } catch (Exception e) {
            log.error("获取可用会议室列表失败", e);
            return ResponseUtil.error("获取可用会议室列表失败");
        }
    }

    /**
     * 获取所有会议室（管理员）
     */
    @GetMapping
    @RequireAuth(roles = {UserRole.ADMIN})
    @Operation(summary = "分页获取所有会议室")
    public Result<IPage<MeetingRoom>> getAllRooms(
            @RequestParam(defaultValue = "1") @Parameter(ref = "页码") Integer current,
            @RequestParam(defaultValue = "10") @Parameter(ref = "每页数量") Integer size) {

        try {
            Page<MeetingRoom> page = new Page<>(current, size);
            IPage<MeetingRoom> result = meetingRoomService.getAllRooms(page);
            return ResponseUtil.success(result);
        } catch (BusinessException e) {
            return ResponseUtil.error(e.getMessage());
        } catch (Exception e) {
            log.error("获取会议室列表失败", e);
            return ResponseUtil.error("获取会议室列表失败");
        }
    }

    /**
     * 添加会议室
     */
    @PostMapping
    @RequireAuth(roles = {UserRole.ADMIN})
    @Operation(summary = "添加会议室")
    public Result<String> addMeetingRoom(
            @RequestBody @Valid @Parameter(ref = "会议室信息") MeetingRoom meetingRoom) {

        try {
            boolean success = meetingRoomService.addMeetingRoom(meetingRoom);
            return success ? ResponseUtil.success("会议室添加成功") :
                    ResponseUtil.error("会议室添加失败");
        } catch (BusinessException e) {
            return ResponseUtil.error(e.getMessage());
        } catch (Exception e) {
            log.error("添加会议室失败", e);
            return ResponseUtil.error("添加会议室失败");
        }
    }

    /**
     * 更新会议室信息
     */
    @PutMapping("/{id}")
    @RequireAuth(roles = {UserRole.ADMIN})
    @Operation(summary = "更新会议室信息")
    public Result<String> updateMeetingRoom(
            @PathVariable @Parameter(ref = "会议室ID") Long id,
            @RequestBody @Valid @Parameter(ref = "会议室信息") MeetingRoom meetingRoom) {

        try {
            boolean success = meetingRoomService.updateMeetingRoom(id, meetingRoom);
            return success ? ResponseUtil.success("会议室更新成功") :
                    ResponseUtil.error("会议室更新失败");
        } catch (BusinessException e) {
            return ResponseUtil.error(e.getMessage());
        } catch (Exception e) {
            log.error("更新会议室失败，ID：{}", id, e);
            return ResponseUtil.error("更新会议室失败");
        }
    }

    /**
     * 删除会议室
     */
    @DeleteMapping("/{id}")
    @RequireAuth(roles = {UserRole.ADMIN})
    @Operation(summary = "删除会议室")
    public Result<String> deleteMeetingRoom(
            @PathVariable @Parameter(ref = "会议室ID") Long id) {

        try {
            boolean success = meetingRoomService.deleteMeetingRoom(id);
            return success ? ResponseUtil.success("会议室删除成功") :
                    ResponseUtil.error("会议室删除失败");
        } catch (BusinessException e) {
            return ResponseUtil.error(e.getMessage());
        } catch (Exception e) {
            log.error("删除会议室失败，ID：{}", id, e);
            return ResponseUtil.error("删除会议室失败");
        }
    }

    /**
     * 员工查看会议室状态
     */
    @GetMapping("/status")
    @RequireAuth(roles = {UserRole.EMPLOYEE, UserRole.ADMIN})
    @Operation(summary = "查看所有会议室状态")
    public Result<List<MeetingRoom>> getRoomStatus() {
        try {
            List<MeetingRoom> rooms = meetingRoomService.getAllRoomStatus();
            return ResponseUtil.success(rooms);
        } catch (BusinessException e) {
            return ResponseUtil.error(e.getMessage());
        } catch (Exception e) {
            log.error("查看会议室状态失败", e);
            return ResponseUtil.error("查看会议室状态失败");
        }
    }

    /**
     * 员工更新会议室状态
     */
    @PutMapping("/{id}/status")
    @RequireAuth(roles = {UserRole.EMPLOYEE, UserRole.ADMIN})
    @Operation(summary = "更新会议室状态")
    public Result<String> updateRoomStatus(
            @PathVariable @Parameter(ref = "会议室ID") Long id,
            @RequestParam @Parameter(ref = "会议室状态") RoomStatus status) {

        try {
            boolean success = meetingRoomService.updateRoomStatus(id, status);
            return success ? ResponseUtil.success("会议室状态更新成功") :
                    ResponseUtil.error("会议室状态更新失败");
        } catch (BusinessException e) {
            return ResponseUtil.error(e.getMessage());
        } catch (Exception e) {
            log.error("更新会议室状态失败，ID：{}, 状态：{}", id, status, e);
            return ResponseUtil.error("更新会议室状态失败");
        }
    }

    /**
     * 根据ID获取会议室详情
     */
    @GetMapping("/{id}")
    @RequireAuth(roles = {UserRole.CUSTOMER, UserRole.EMPLOYEE, UserRole.ADMIN})
    @Operation(summary = "根据ID获取会议室详情")
    public Result<MeetingRoom> getRoomById(
            @PathVariable @Parameter(ref = "会议室ID") Long id) {

        try {
            MeetingRoom room = meetingRoomService.getRoomById(id);
            if (room == null) {
                return ResponseUtil.error("会议室不存在");
            }
            return ResponseUtil.success(room);
        } catch (Exception e) {
            log.error("获取会议室详情失败，ID：{}", id, e);
            return ResponseUtil.error("获取会议室详情失败");
        }
    }

    /**
     * 获取会议室统计信息
     */
    @GetMapping("/statistics")
    @RequireAuth(roles = {UserRole.ADMIN})
    @Operation(summary = "获取会议室统计信息")
    public Result<Object> getRoomStatistics() {
        try {
            long totalRooms = meetingRoomService.countByStatus(null);
            long availableRooms = meetingRoomService.countByStatus(RoomStatus.AVAILABLE);
            long lockedRooms = meetingRoomService.countByStatus(RoomStatus.LOCKED);
            long reservedRooms = meetingRoomService.countByStatus(RoomStatus.RESERVED);
            long inUserRooms = meetingRoomService.countByStatus(RoomStatus.IN_USE);
            long maintenanceRooms = meetingRoomService.countByStatus(RoomStatus.MAINTENANCE);


            return ResponseUtil.success(java.util.Map.of(
                    "total", totalRooms,
                    "available", availableRooms,
                    "maintenance", maintenanceRooms,
                    "lockedRooms", lockedRooms,
                    "reservedRooms", reservedRooms,
                    "inUserRooms", inUserRooms
            ));
        } catch (Exception e) {
            log.error("获取会议室统计信息失败", e);
            return ResponseUtil.error("获取统计信息失败");
        }
    }

    /**
     * 批量更新会议室状态
     */
    @PutMapping("/batch-status")
    @RequireAuth(roles = {UserRole.ADMIN})
    @Operation(summary = "批量更新会议室状态")
    public Result<String> batchUpdateStatus(
            @RequestParam @Parameter(ref = "会议室ID列表") List<Long> roomIds,
            @RequestParam @Parameter(ref = "新状态") RoomStatus status) {

        try {
            int successCount = meetingRoomService.batchUpdateStatus(roomIds, status);
            return ResponseUtil.success(String.format("批量更新完成，成功更新 %d 个会议室", successCount));
        } catch (BusinessException e) {
            return ResponseUtil.error(e.getMessage());
        } catch (Exception e) {
            log.error("批量更新会议室状态失败", e);
            return ResponseUtil.error("批量更新失败");
        }
    }
}